package org.elasticsearch;

import org.elasticsearch.action.ActionModule;
import org.elasticsearch.common.component.Lifecycle;
import org.elasticsearch.common.component.LifecycleListener;
import org.elasticsearch.common.transport.BoundTransportAddress;
import org.elasticsearch.http.HttpInfo;
import org.elasticsearch.http.HttpServerTransport;
import org.elasticsearch.http.HttpStats;
import org.elasticsearch.http.netty4.Netty4HttpRequest;
import org.elasticsearch.rest.RestChannel;
import org.elasticsearch.rest.RestController;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;


/**
 * Created by Administrator on 2017/7/4 0004.
 */
public class Netty4HttpServerTransport implements HttpServerTransport {
    private static int workerCount = 8;
    private ServerBootstrap serverBootstrap;

    public Netty4HttpServerTransport(RestController restController) {
        this.restController = restController;
    }

    private RestController restController;

    protected final List<Channel> serverChannels = new ArrayList<>();


    public static void main(String[] args){
        ActionModule actionModule = new ActionModule();
        actionModule.initRestHandlers();
        RestController controller = actionModule.getRestController();
        Netty4HttpServerTransport transport = new Netty4HttpServerTransport(controller);
        transport.doStart();
    }

    private ChannelHandler configureServerChannelHandler() {
        return new HttpChannelHandler(this, true);
    }


    public void doStart(){
        boolean success = false;
        try {
            serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(new NioEventLoopGroup(workerCount));
            serverBootstrap.channel(NioServerSocketChannel.class);

            serverBootstrap.childHandler(configureServerChannelHandler());

            serverBootstrap.childOption(ChannelOption.TCP_NODELAY, true);
            serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
            serverBootstrap.option(ChannelOption.SO_REUSEADDR, false);
            serverBootstrap.childOption(ChannelOption.SO_REUSEADDR, false);
            try {
                ChannelFuture future = serverBootstrap.bind(new InetSocketAddress("127.0.0.1", 9700)).sync();
                serverChannels.add(future.channel());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            success = true;
        } finally {
            if (success == false) {
                doStop();
            }
        }
    }

    private void doStop() {




    }


    public void dispatchRequest(Netty4HttpRequest httpRequest, RestChannel channel) {
        restController.dispatchRequest(httpRequest,channel);
    }

    @Override
    public void close() {

    }

    @Override
    public Lifecycle.State lifecycleState() {
        return null;
    }

    @Override
    public void addLifecycleListener(LifecycleListener listener) {

    }

    @Override
    public void removeLifecycleListener(LifecycleListener listener) {

    }

    @Override
    public void start() {

    }

    @Override
    public void stop() {

    }

    @Override
    public BoundTransportAddress boundAddress() {
        return null;
    }

    @Override
    public HttpInfo info() {
        return null;
    }

    @Override
    public HttpStats stats() {
        return null;
    }
}
